import CryptoJS from 'crypto-js';
import pako from 'pako';
import { Base64 } from 'js-base64';

// 配置参数
const SECRETKEY = "liuzhououlaipu66"; // 必须与Java保持一致
const IV_LENGTH = 16;

// ================== 加密流程 ================== //
/**
 * JS加密（与Java互操作）
 * @param {Object|string} data - 待加密数据
 * @returns {string} Base64加密字符串
 */
function encryptWithCompress(data) {
    // Step1：JSON序列化
    const jsonStr = typeof data === 'string' ? data : JSON.stringify(data);

    // Step2：GZIP压缩
    const compressed = pako.gzip(jsonStr,  { level: 6 });

    // Step3：生成随机IV
    const iv = CryptoJS.lib.WordArray.random(IV_LENGTH);

    // Step4：AES加密
    const key = CryptoJS.enc.Utf8.parse(SECRETKEY);
    const cipher = CryptoJS.AES.encrypt(
        CryptoJS.lib.WordArray.create(compressed),
        key,
        {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }
    );

    // Step5：拼接IV+密文 → Base64
    const ivBytes = CryptoJS.enc.Hex.parse(iv.toString(CryptoJS.enc.Hex));
    const combined = ivBytes.concat(cipher.ciphertext);
    return combined.toString(CryptoJS.enc.Base64);
}

// ================== 解密流程 ================== //
/**
 * JS解密（兼容Java加密数据）
 * @param {string} encryptedBase64 - Java加密字符串
 * @returns {Object} 原始数据
 */
function decryptWithDecompress(encryptedBase64) {
    // Step1：Base64解码（处理Apache格式）
    const rawData = Base64.toUint8Array(encryptedBase64.replace(/\n/g,  ''));

    // Step2：提取IV和密文
    const ivBytes = rawData.slice(0,  IV_LENGTH);
    const cipherBytes = rawData.slice(IV_LENGTH);

    // Step3：AES解密配置
    const key = CryptoJS.enc.Utf8.parse(SECRETKEY);
    const iv = CryptoJS.lib.WordArray.create(ivBytes);

    // Step4：执行解密
    const decrypted = CryptoJS.AES.decrypt(
        { ciphertext: CryptoJS.lib.WordArray.create(cipherBytes)  },
        key,
        { iv: iv, padding: CryptoJS.pad.Pkcs7  }
    );

    // Step5：GZIP解压
    const uint8Array = new Uint8Array(decrypted.sigBytes);
    decrypted.words.forEach((word,  i) => {
        uint8Array[i*4] = (word >> 24) & 0xff;
        uint8Array[i*4+1] = (word >> 16) & 0xff;
        uint8Array[i*4+2] = (word >> 8) & 0xff;
        uint8Array[i*4+3] = word & 0xff;
    });

    try {
        const decompressed = pako.ungzip(uint8Array);
        const str = new TextDecoder().decode(decompressed);
        return JSON.parse(str);
    } catch (e) {
        throw new Error(`解密失败：${e.message}`);
    }
}
export {
    encryptWithCompress, decryptWithDecompress,
}
